﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using tactics.Commands;
using tactics.Abilities;

namespace tactics
{
    using Coord = Utility.Pair<int, int>;
    using HighlightArea = Dictionary<int, int>;

    class AbilitySelected : ISelectionMode
    {
        HighlightArea abilityAreaHighlight;
        Unit unitSelected;
        Player unitOwner;

        Ability ability;

        Func<Unit, Dictionary<int, int>> unitMoveHighlightFunc;
        Func<Unit, Player, Ability, Dictionary<int, int>> abilityAreaHighlightFunc;

        public Unit SelectedUnit
        {
            get { return unitSelected; }
        }

        public Player UnitOwner
        {
            get { return unitOwner; }
        }

        public AbilitySelected(Unit unit, Player player, Ability abilityIn, Func<Unit, Dictionary<int, int>> unitMoveHighlightFuncIn, Func<Unit, Player, Ability, Dictionary<int, int>> abilityAreaHighlightFuncIn)
        {
            unitMoveHighlightFunc = unitMoveHighlightFuncIn;
            
            ability = abilityIn;

            if (TacticsEngine.Instance.Game.TurnManager.UnitTurn == null ||
                TacticsEngine.Instance.Game.TurnManager.UnitTurn == unit)
                abilityAreaHighlightFunc = abilityAreaHighlightFuncIn;
            else
                abilityAreaHighlightFunc = null;

            abilityAreaHighlight = abilityAreaHighlightFunc(unit, player, ability);

            unitSelected = unit;
            unitOwner = player;
        }

        public ISelectionMode ClickUnit(Unit unit, Player player)
        {
            Coord unitCoord = new Coord(unit.X, unit.Y);

            if (ability.HasAoEComponent && IsInHighlightArea(unitCoord))
            {
                CommandQueue.Instance.AddCommand(new ApplyAbilityToAreaCommand(ability, unitSelected, unitCoord));
            }
            else if (IsInHighlightArea(new Coord(unit.X, unit.Y)))
            {
                CommandQueue.Instance.AddCommand(new ApplyAbilityToUnitCommand(ability, unitSelected, unit));
            }

            return null;
        }

        // clicked to move IF in highlight area, else deselect
        public ISelectionMode ClickNothing(Coord coord)
        {
            // apply ability to area, end selection
            if (ability.HasAoEComponent && IsInHighlightArea(coord))
            {
                CommandQueue.Instance.AddCommand(new ApplyAbilityToAreaCommand(ability, unitSelected, coord));
            }
            else if (IsInHighlightArea(coord))
            {
                return this;
            }
            else
                return new UnitSelected(unitSelected, unitOwner, unitMoveHighlightFunc);

            return null;
        }

        public Dictionary<int, int> GetHighlightArea()
        {
            return abilityAreaHighlight;
        }

        private bool IsInHighlightArea(Utility.Pair<int, int> coord)
        {
            return abilityAreaHighlight.ContainsKey(TacticsEngine.Instance.Game.AtCoord(coord));
        }
    }
}
